package org.example.java.lang;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Method;

/**
 * User: ZhangJuntao
 * Date: 13-4-13
 * Time: 下午7:06
 */
public class CustomClassLoaderTest {
  static class CustomClassLoader extends ClassLoader {
    public Class<?> findClass(String name) throws ClassNotFoundException {
      byte[] b = null;
      try {
        try {
          if (getParent() != null) {
            return loadClass(name);
          }
        } catch (ClassNotFoundException e) {
          // ClassNotFoundException thrown if class not found
          // from the non-null parent class loader
        }

        b = loadClassData(CustomClassLoader.formatClassName(name));
      } catch (Exception e) {
        e.printStackTrace();
      }
      return defineClass(name, b, 0, b.length);

    }

    private byte[] loadClassData(String filePath) throws Exception {
      int n = 0;
      BufferedInputStream br = new BufferedInputStream(new FileInputStream(new File(filePath)));
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      while ((n = br.read()) != -1) {
        bos.write(n);
      }
      br.close();
      return bos.toByteArray();
    }

    /*
     * 格式化文件所对应的路径
     */
    public static String formatClassName(String name) {
      return "JavaSE/target/classes/" + name.replace(".","/") + ".class";
    }
  }

  /*
  * main方法测试
  */
  public static void main(String[] args) throws Exception {

    CustomClassLoader acl = new CustomClassLoader();
    Class c = acl.findClass("Hello"); //代替 Class cc= Class.forName("Hello");
    Object obj = c.newInstance();
    Method m = c.getMethod("setName", new Class[]{String.class});
    m.invoke(obj, "你好");
    System.out.println(c.getName());
    System.out.println(c.getClassLoader());
    System.out.println(c.getClassLoader().getParent());

    System.out.println("=========================================");

    Class tbc = Class.forName("org.example.java.lang.TestBeLoader");
//    Class tbc = acl.findClass("org.example.java.lang.TestBeLoader");
//    Class tbc = acl.loadClass("org.example.java.lang.TestBeLoader");
    System.out.println(tbc.getClassLoader());
    System.out.println(TestBeLoader.class.getClassLoader());

    TestBeLoader testBeLoader = (TestBeLoader)tbc .newInstance();
    System.out.println(testBeLoader.getClass().getClassLoader());
    testBeLoader.sayHello();
  }

}
